﻿using System;
using System.Collections.Specialized;
using System.ComponentModel.Design;
using Microsoft.Practices.Common;
using Microsoft.Practices.ComponentModel;
using Microsoft.Practices.RecipeFramework;
using Sixeyed.Guidance.CodeGeneration.ValueProviders.Helpers;

namespace Sixeyed.Guidance.CodeGeneration.ValueProviders
{
    /// <summary>
    /// Provides a default value for a given type
    /// </summary>
    [ServiceDependency(typeof(IDictionaryService))]
    public class DefaultValueProvider : ValueProvider, IAttributesConfigurable
    {
        private string qualifiedTypeName;

        /// <summary>
        /// Configures provider, loading type name from arguments
        /// </summary>
        /// <param name="attributes">Argument dictionary</param>
        public void Configure(StringDictionary attributes)
        {
            this.qualifiedTypeName = ValueProviderHelper.GetOptionalArgumentValue(attributes, ArgumentName.QualifiedTypeName);
        }

        /// <summary>
        /// Provides updated argument value, if not already populated
        /// </summary>
        /// <param name="currentValue">Current argument value</param>
        /// <param name="newValue">New argument value</param>
        /// <returns>Whether argument value was updated</returns>
        public override bool OnBeginRecipe(object currentValue, out object newValue)
        {
            bool updated = false;
            //only update if the value isn't set:
            if (currentValue != null)
            {
                newValue = null;
            }
            else
            {
                newValue = GetDefaultValue();
                updated = true;
            }
            return updated;
        }

        private object GetDefaultValue()
        {
            object value = null;
            if (!string.IsNullOrEmpty(this.qualifiedTypeName))
            {
                Type type = Type.GetType(this.qualifiedTypeName);
                value = Activator.CreateInstance(type);
            }
            return value;
        }

        private struct ArgumentName
        {
            public const string QualifiedTypeName = "QualifiedTypeName";
        }
    }
}
